home *** CD-ROM | disk | FTP | other *** search
- From: decvax!vax135!hou3c!ka
- Date: Mon, 21 Jan 85 22:07:41 est
- Newsgroups: mod.sources
- Subject: Vnews part 3
-
- # Welcome to vnews release 2.11-B 1/17/85.
- # This is part 3 out of 7.
- # Feed me into sh (NOT csh).
-
- if test ! -d lib
- then mkdir lib
- fi
-
- cat > lib/gethead.c <<\!E!O!F!
- #include <stdio.h>
- #include <sys/types.h>
- #include "config.h"
- #include "defs.h"
- #include "arthead.h"
-
-
- static char *hdname[NHDNAME + 1] = {
- "Relay-Version",
- "Posting-Version",
- "Path",
- "From",
- "Newsgroups",
- "Subject",
- "Message-ID",
- "Date",
- "Article-I.D.",
- "Posted",
- "Date-Received",
- "Expires",
- "References",
- "Control",
- "Sender",
- "Reply-To",
- "Followup-To",
- "Distribution",
- "Organization",
- "Lines",
- "Keywords",
- "Approved",
- "Summary",
- "Priority",
- 0
- };
-
-
-
- FILE *
- gethead(hp, fp)
- register struct arthead *hp ;
- FILE *fp ;
- {
- char line[LBUFLEN] ;
- register char *p ;
- register char **pp ;
- register int i ;
- char *spnext ;
- int spleft ;
- int spnum ;
- int unreccnt ;
- extern char FULLSYSNAME[] ;
- char *index(), *ckmalloc() ;
- char *hfgets() ;
-
- for (pp = &hp->h_from, i = NHDNAME + NUNREC ; --i >= 0 ; *pp++ = 0) ;
- unreccnt = 0 ;
- spleft = 0 ;
- spnum = 0 ;
- while (hfgets(line, LBUFLEN, fp) != NULL && line[0] != '\n') {
- if ((p = index(line, ':')) == NULL)
- goto bad ;
- *p = '\0' ;
- if (index(line, ' ') != NULL) /* this test unnecessary */
- goto bad ;
- for (pp = hdname ; *pp ; pp++) {
- if (**pp == line[0] && strcmp(*pp, line) == 0)
- break ;
- }
- if (*pp) {
- while (*++p == ' ') ;
- if (pp == hdname + 2) { /* Path: */
- if (prefix(p, FULLSYSNAME)
- && index(NETCHRS, p[i = strlen(FULLSYSNAME)]))
- p += i + 1 ;
- }
- pp = &hp->h_relayversion + (pp - hdname) ;
- } else {
- *p = ':' ;
- p = line ;
- if (unreccnt >= NUNREC)
- continue ; /* ignore if won't fit */
- pp = &hp->h_unrec[unreccnt++] ;
- }
- nstrip(p) ;
- i = strlen(p) + 1;
- if (i > spleft) {
- if (spnum >= 8)
- xerror("Out of header space") ;
- if (hp->h_space[spnum] == NULL)
- hp->h_space[spnum] = ckmalloc(H_SPACE) ;
- spnext = hp->h_space[spnum++] ;
- spleft = H_SPACE ;
- }
- *pp = spnext ;
- strcpy(spnext, p) ;
- spnext += i ;
- spleft -= i ;
- }
- if (hp->h_from != NULL && hp->h_path != NULL && hp->h_subdate != NULL && hp->h_ident != NULL)
- return fp ;
- bad:
- return NULL ;
- }
- !E!O!F!
-
- cat > lib/getopt.c <<\!E!O!F!
- /*
- * getopt - get option letter from argv
- * This version of getopt was written by Henry Spencer
- * and is in the public domain.
- */
-
- #include <stdio.h>
- #include "config.h"
-
- char *optarg; /* Global argument pointer. */
- int optind = 0; /* Global argv index. */
-
- static char *scan = NULL; /* Private scan pointer. */
-
- extern char *index();
-
- int
- getopt(argc, argv, optstring)
- int argc;
- char *argv[];
- char *optstring;
- {
- register char c;
- register char *place;
-
- optarg = NULL;
-
- if (scan == NULL || *scan == '\0') {
- if (optind == 0)
- optind++;
-
- place = argv[optind];
- if (optind >= argc || place[0] != '-' || place[1] == '\0')
- return(EOF);
- optind++;
- if (strcmp(place, "--")==0) {
- return(EOF);
- }
-
- scan = place + 1;
- }
-
- c = *scan++;
- place = index(optstring, c);
-
- if (place == NULL || c == ':') {
- fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
- return('?');
- }
-
- place++;
- if (*place == ':') {
- if (*scan != '\0') {
- optarg = scan;
- scan = NULL;
- } else {
- if ((optarg = argv[optind]) == NULL) {
- fprintf(stderr, "%s: no arg for -%c option\n", c);
- return('?');
- }
- optind++;
- }
- }
-
- return(c);
- }
- !E!O!F!
-
- cat > lib/getuser.c <<\!E!O!F!
- /*
- * Get the user's name and home directory.
- */
-
- #include "config.h"
- #include <stdio.h>
-
-
- getuser() {
- extern char *username, *userhome;
- extern char *getenv();
-
- #if USGREL > 6
- username = getenv("LOGNAME") ;
- #else
- username = getenv("USER") ;
- #endif
- if ((userhome = getenv("HOME")) == NULL)
- userhome = getenv("LOGDIR") ; /* PWB??? */
-
- /* if not in environment, get from /etc/passwd file */
- if (username == NULL || userhome == NULL)
- pgetuser() ;
- }
- !E!O!F!
-
- cat > lib/gfopen.c <<\!E!O!F!
- #include <stdio.h>
- #include "defs.h"
- #include "libextern.h"
-
- FILE *ngfp ;
- int maxng ;
-
-
- gfopen() {
- char buf[FPATHLEN] ;
-
- sprintf(buf, "%s/groupfile", LIB);
- if ((ngfp = fopen(buf, "r")) == NULL
- && (sleep(2), ngfp = fopen(buf, "r")) == NULL)
- xerror("can't open newsgroup file") ;
- if (fgets(buf, sizeof buf, ngfp) == NULL)
- xerror("newsgroup file is empty") ;
- maxng = atoi(buf) ;
- }
-
-
- gfclose() {
- fclose(ngfp) ;
- ngfp = NULL ;
- }
- !E!O!F!
-
- cat > lib/hash.c <<\!E!O!F!
- /*
- * Hashing function.
- * First arg is the string, second is the number of elements in the table.
- * Currently, we use a CRC.
- */
-
- int
- hash(string, nelem)
- char *string ;
- {
- register unsigned char *p ;
- register int h ;
-
- h = 0 ;
- for (p = string ; *p ; ) {
- h = (long)(((long)h << 8) + *p++) % nelem ;
- }
- return h ;
- }
- !E!O!F!
-
- cat > lib/hfgets.c <<\!E!O!F!
- #include <stdio.h>
-
- /*
- * hfgets is like fgets, but deals with continuation lines.
- * It also ensures that even if a line that is too long is
- * received, the remainder of the line is thrown away
- * instead of treated like a second line.
- */
-
- char *
- hfgets(buf, len, fp)
- char *buf;
- int len;
- register FILE *fp;
- {
- register int c;
- register char *cp;
-
- cp = fgets(buf, len, fp);
- if (cp == NULL || *cp == '\n')
- return cp;
-
- c = strlen(cp);
- len -= c;
- cp += c - 1;
- if (*cp != '\n') {
- /* Line too long - part read didn't fit into a newline */
- while ((c = getc(fp)) != '\n' && c != EOF);
- }
- while ((c = getc(fp)) == ' ' || c == '\t') { /* for each cont line */
- /* Continuation line. */
- while ((c = getc(fp)) == ' ' || c == '\t'); /* skip white space */
- if (--len > 0)
- *cp++ = ' ';
- do {
- if (--len > 0)
- *cp++ = c ;
- } while ((c = getc(fp)) != '\n' && c != EOF) ;
- }
- *cp++ = '\n';
- *cp++ = '\0';
- if (c != EOF) /* Bug in Apollo UN*X */
- ungetc(c, fp); /* push back first char of next header */
- return buf;
- }
- !E!O!F!
-
- cat > lib/hfree.c <<\!E!O!F!
- /*
- * Free up the storage used by a header.
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include "arthead.h"
-
-
- hfree(hp)
- struct arthead *hp ;
- {
- register int i ;
- register char **p ;
-
- for (i = 8, p = hp->h_space ; --i >= 0 ; p++) {
- if (*p != NULL) {
- free(*p) ;
- *p = NULL ;
- }
- }
- }
- !E!O!F!
-
- cat > lib/hxchg.c <<\!E!O!F!
- /*
- * Exchange two headers.
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include "arthead.h"
-
- hxchg(hp1, hp2)
- struct arthead *hp1, *hp2 ;
- {
- register char *p, *q ;
- register char c ;
- register int i ;
-
- p = (char *)hp1, q = (char *)hp2 ;
- for (i = sizeof(struct arthead) ; --i >= 0 ; )
- c = *p, *p++ = *q, *q++ = c ;
- }
- !E!O!F!
-
- cat > lib/index.c <<\!E!O!F!
- /*
- * Return the ptr in sp at which the character c appears;
- * NULL if not found
- *
- * These are the v7 index and rindex routines. The makefile does not
- * place them it the library because every version of UN*X that is
- * supported by this release of netnews has these routines (possibly
- * named strchr/strrchr). If you are running V6, use these routines.
- */
-
- char *
- index(sp, c)
- register char *sp, c;
- {
- do {
- if (*sp == c)
- return(sp);
- } while (*sp++);
- return(NULL);
- }
-
- /*
- * Return the ptr in sp at which the character c last
- * appears; NULL if not found
- */
-
- char *
- rindex(sp, c)
- register char *sp, c;
- {
- register char *r;
-
- r = NULL;
- do {
- if (*sp == c)
- r = sp;
- } while (*sp++);
- return(r);
- }
- !E!O!F!
-
- cat > lib/isadmin.c <<\!E!O!F!
- #include <stdio.h>
- #include "defs.h"
- #ifndef ROOTID
- #include <pwd.h>
- #endif
-
-
- /*
- * Return 1 if the user is the superuser or the netnews administrator.
- */
- isadmin() {
- int uid ;
- #ifndef ROOTID
- struct passwd *pw ;
- #endif
-
- if ((uid = getuid()) == 0) /* superuser */
- return 1 ;
- #ifdef ROOTID
- return uid == ROOTID ;
- #else
- return (pw = getpwnam(ADMIN)) != NULL && pw->pw_uid == uid ;
- #endif
- }
-
-
- /* The following code is better for backward compatability, but
- too complex for my liking:
-
- (*
- * No hardwired administrator ID, so we have to do this the
- * hard way. First we find the person to be notified. If
- * that fails, we try the user HOME.
- *)
-
- #ifdef NOTIFY
- char notify[64] ;
- char fname[64] ;
- FILE *nfd ;
-
- sprintf(fname, "%s/notify", LIB);
- nfd = fopen(fname, "r");
- if (nfd == NULL)
- strcpy(notify, NOTIFY) ;
- else if (fscanf(nfd, "%s", TELLME) == EOF)
- goto nonotify;
- if ((pw = getpwnam(notify)) == NULL)
- goto nonotify;
- return pw->pw_uid == uid;
- #endif
-
- nonotify:
- #ifdef HOME
- return (pw = getpwnam(HOME)) != NULL && pw->pw_uid == uid;
- #else
- return 0;
- #endif
- #endif ROOTID
- }
- */
- !E!O!F!
-
- cat > lib/isre.c <<\!E!O!F!
- /*
- * Check for "Re: " at beginning of string.
- */
-
- isre(t)
- register char *t ;
- {
- if (t == 0) /* delete this later */
- return 0 ;
- if (strncmp(t, "Re:", 3) == 0
- || strncmp(t, "re:", 3) == 0
- || strncmp(t, "RE:", 3) == 0)
- return 1 ;
- return 0 ;
- }
- !E!O!F!
-
- cat > lib/launder.c <<\!E!O!F!
- /*
- * nglist is the list of newsgroups in an article we want to follow up.
- * Do any special fascist processing to prevent certain kinds of followups.
- * In this case, there are two things we want to do:
- * All followups to "net.general" are fed to "net.followup".
- * However, if "net.general" is mentioned along with "net.news.group",
- * just remove the net.general.
- */
-
- #include "config.h"
-
- char *index();
-
- launder(nglist)
- char *nglist;
- {
- char *cp;
- char outbuf[128];
- int seen_group = 0;
-
- for (cp = index(nglist, 'n'); cp; cp = index(cp + 1, 'n'))
- if (strncmp("news.group", cp, 10) == 0)
- seen_group++;
- for (cp = index(nglist, 'n'); cp; cp = index(cp + 1, 'n'))
- if (strncmp("net.general", cp, 11) == 0) {
- /* 11 = strlen("net.general") */
- strcpy(outbuf, cp + 11);
- if (!seen_group) {
- strcpy(cp, "net.followup");
- cp += 12; /* 12 = strlen("net.followup") */
- }
- if (cp[-1] == ',' && outbuf[0] == ',')
- cp--;
- strcpy(cp, outbuf);
- }
- }
- !E!O!F!
-
- cat > lib/lcase.c <<\!E!O!F!
- #include <ctype.h>
-
- #ifdef _tolower
- #define tolower(c) _tolower(c)
- #endif
-
-
- lcase(s)
- register char *s;
- {
- register char *ptr;
-
- for (ptr = s; *ptr; ptr++)
- if (isupper(*ptr))
- *ptr = tolower(*ptr);
- }
- !E!O!F!
-
- cat > lib/letter <<\!E!O!F!
- To: cbosgd!uucp-news
- Subject: Vnews status
-
- I have done quite a bit to the vnews internals.
-
- Vnews now generates the article index for a newsgroup using a file
- called artfile instead of openning each article in the newsgroup;
- this makes entering a new newsgroup faster. Currently records
- are added to artfile by a program called afinsert which is invoked
- from the sys file. This requires a mod to inews to pass the history
- line to afinsert. There is a program called afbuild which rebuilds
- artfile from the history file. Since afbuild has to open all the
- articles in the spool file, it takes about as long to run as the
- expire program does, which I hope is acceptable. Of course, expire
- could be rewritten to deal with both artfile and the history file
- at some point.
-
- I have changed the vnews source around quite a bit. I have squeezed
- it to the point where it should fit on a PDP-11. One problem I faced
- was that the files funcs.c and rfuncs.c contained a number of routines
- that were not needed for netnews, so vnews currently does not share
- any source code with the rest of netnews. What I have done, however,
- is to take many of the vnews routines and put them in a library called
- rlib.a so that they can be used by other netnews programs. The file
- /usr/local/src/cmd/news/lib/routines.doc on cbosgd contains a copy of
- the documentation on the routines in rlib.a. I can mail a copy to
- this list if people don't have access to cbosgd.
-
- The library comes with a shell program called setup to handle compila-
- tion options. This is hopefully a simpler approach than the localize.sh
- stuff that comes with release 2.10. (For example, if you do not specify
- which version of UNIX you are running under, setup figures it out.)
- Setup creates files named config.h and newsdefs.h, which specify the
- oeprating system and other news parameters, respectively. It also
- creates a file called makedefs, which can be prepended to a makefile or
- shell procedure. Setup currently does not define everything that pro-
- grams like inews need, but it could be expanded without too much difficulty.
-
- The "ud" (unsibscribe to discussion) command has been installed in vnews
- but needs a little work. The rest of vnews appears to be in pretty good
- shape at this point.
-
- I am not going to be able to do much on vnews for the next several weeks,
- but I would like to try to get a release of netnews out sometime in the
- forseeable future. How are other pieces coming?
- Kenneth Almquist
- !E!O!F!
-
- cat > lib/libextern.h <<\!E!O!F!
- /*
- * Extern variables defined by library routines.
- */
-
- extern char LIB[]; /* /usr/lib/news */
- extern char SPOOL[]; /* spool directory */
- extern char FULLSYSNAME[]; /* system name */
- extern char DOMAIN[]; /* append to FULLSYSNAME to get domain name */
- extern char MAILPARSER[]; /* recmail program */
- extern char XINEWS[]; /* inews program */
- extern char CAESAR[]; /* caesar decryption program */
- extern char newsrc[]; /* name of .newsrc file */
- extern char *username; /* user's login name */
- extern char *userhome; /* user's login directory */
- extern char bfr[]; /* general purpose buffer */
- !E!O!F!
-
- cat > lib/logdir.c <<\!E!O!F!
- /*
- * UNIX shell - logdir routine
- *
- * Joe Steffen
- * Bell Telephone Laboratories
- *
- * This routine does not use the getpwent(3) library routine
- * because the latter uses the stdio package. The allocation of
- * storage in this package destroys the integrity of the shell's
- * storage allocation.
- *
- * Modified 2/82 by DJ Molny
- *
- * This routine now implements name cacheing, so multiple requests
- * for the same logdir do not result in multiple open/reads of
- * /etc/passwd. If the previous request was successful and the name
- * is the same as the last request, the same login directory is returned.
- */
-
- #define BUFSIZ 160
-
- static char line[BUFSIZ+1];
-
- char *
- logdir(name)
- char *name;
- {
- int pwf;
- static char lastname[BUFSIZ+1];
- static char lastdir[BUFSIZ+1];
- register char *p;
- register int i, j;
- char *field();
-
- if (*lastdir && !strcmp(lastname,name)) /* djm */
- return(lastdir);
-
- strcpy(lastname,name); /* djm */
- strcpy(lastdir,""); /* djm */
-
- /* attempt to open the password file */
- if ((pwf = open("/etc/passwd", 0)) == -1)
- return(0);
-
- /* find the matching password entry */
- do {
- /* get the next line in the password file */
- i = read(pwf, line, BUFSIZ);
- for (j = 0; j < i; j++)
- if (line[j] == '\n')
- break;
- /* return a null pointer if the whole file has been read */
- if (j >= i)
- return(0);
- line[++j] = 0; /* terminate the line */
- lseek(pwf, (long) (j - i), 1); /* point at the next line */
- p = field(line); /* get the logname */
- } while (strcmp(name, line) != 0);
- close(pwf);
-
- /* skip the intervening fields */
- p = field(p);
- p = field(p);
- p = field(p);
- p = field(p);
-
- /* return the login directory */
- field(p);
- strcpy(lastdir,p); /* djm */
- return(p);
- }
-
- static char *
- field(p)
- register char *p;
- {
- while (*p && *p != ':')
- ++p;
- if (*p) *p++ = 0;
- return(p);
- }
- !E!O!F!
-
- cat > lib/lookup.c <<\!E!O!F!
- #include <stdio.h>
- #include "af.h"
-
-
- /*
- * Look up an article using the article id.
- */
-
- DPTR
- lookart(id, a)
- char *id ;
- struct artrec *a ;
- {
- DPTR dp ;
-
- dp = readptr(hashid(id)) ;
- while (dp != DNULL) {
- readrec(dp, a) ;
- if (equal(id, a->a_ident)) {
- /*printf("lookart %s succeeded\n", id) ; /*DEBUG*/
- return dp ;
- }
- dp = a->a_idchain ;
- }
- /*printf("lookart %s failed\n", id) ; /*DEBUG*/
- return DNULL ;
- }
- !E!O!F!
-
- cat > lib/makehimask.c <<\!E!O!F!
- /*
- * Unless the newsgroup is asked for explicitly, delete it from the
- * subscription list.
- */
-
- #include <stdio.h>
- #include "config.h"
- #include "str.h"
-
- makehimask(sublist, ngrp)
- register char *sublist ;
- char *ngrp ;
- {
- char c, *p ;
- char *index() ;
-
- for (;;) {
- if (prefix(sublist, ngrp)
- && (c = sublist[strlen(ngrp)]) == '\0' || c == ',')
- return ;
- if ((p = index(sublist, ',')) == NULL)
- break ;
- sublist = p + 1 ;
- }
- while (*sublist)
- sublist++ ;
- if (sublist[-1] != ',')
- *sublist++ = ',' ;
- *sublist++ = '!' ;
- scopy(ngrp, sublist) ;
- }
- !E!O!F!
-
- cat > lib/mkconfig <<\!E!O!F!
- #!/bin/sh
- if test "$1" = ""
- then echo "Usage: mkconfig dir"
- echo "where dir is the directory containing the 2.10.1 source"
- exit 1
- fi
-
- if test ! -d $1
- then echo "mkconfig: $1: no such directory"
- exit 1
- fi
-
- (
- sed -n -e 's/^NEWSUSR *= */newsusr /p' \
- -e 's/^NEWSGRP *= */newsgrp /p' \
- -e 's/^LIBDIR *= */lib /p' \
- -e 's/^BINDIR *= */bin /p' \
- -e 's/^SPOOLDIR *= */spool /p' \
- $1/Makefile
- sed -n -e 's/^#define[ ]NOTIFY[ ]*"\([^"]*\)".*/notify \1/p' \
- -e 's/^#define[ ]MYDOMAIN[ ]*"\([^"]*\)".*/mydomain \1/p' \
- -e 's/^#define[ ]MYORG[ ]*"\([^"]*\)".*/myorg \1/p' \
- -e 's/^#define[ ]DFLTSUB[ ]*"\([^"]*\)".*/dfltsub \1/p' \
- -e 's/^#define[ ]ADMSUB[ ]*"\([^"]*\)".*/admsub \1/p' \
- -e 's/^#define[ ]UNAME.*/uname/p' \
- -e 's/^#define[ ]GHNAME.*/ghname/p' \
- -e 's/^\/\*[ ]*#define[ ]INTERNET.*/internet no/p' \
- -e 's/^\/\*[ ]*#define[ ]V7MAIL.*/v7mail no/p' \
- -e 's/^#define[ ]X[ ]*"\([^"]*\)".*/x \1/p' \
- $1/defs.h
- rootid=`sed -n -e 's/^#define[ ]ROOTID[ ]*\([0-9]*\).*/\1/p' $1/defs.h`
- rootname=`sed -n -e "/^[^:]*:[^:]*:$rootid:/s/:.*//p" /etc/passwd | sed '2,$d'`
- if test "$rootname" != ""
- then echo admin $rootname
- fi
- ) | sed -e '/lib \/usr\/lib\/news/d' \
- -e '/bin \/usr\/bin/d' \
- -e '/spool \/usr\/spool\/news/d' \
- -e '/dfltsub all/d' \
- -e '/admsub general,all\.announce/d' \
- > config
- !E!O!F!
- chmod +x lib/mkconfig
-
- cat > lib/mypathinit.c <<\!E!O!F!
- #include <stdio.h>
- #include "config.h"
- #include "defs.h"
-
-
- #ifdef HOME
- char SPOOL[FPATHLEN];
- char LIB[FPATHLEN-15];
- char CAESAR[FPATHLEN];
- #else
- char SPOOL[] = SPOOLDIR";
- char LIB[] = LIBDIR";
- char CAESAR[] = LIBDIR/caesar";
- #endif HOME
- #ifdef MYNAME
- char FULLSYSNAME[] = MYNAME;
- #else
- #ifdef UNAME
- #include <sys/utsname.h>
- char FULLSYSNAME[9];
- #else
- char FULLSYSNAME[20];
- #endif UNAME
- #endif MYNAME
- char DOMAIN[] = MYDOMAIN;
- #ifdef SENDMAIL
- char MAILPARSER[] = SENDMAIL;
- #else
- #ifdef HOME
- char MAILPARSER[FPATHLEN];
- #else
- char MAILPARSER[] = LIBDIR/recmail";
- #endif HOME
- #endif SENDMAIL
- char XINEWS[] = INEWS;
- static char verpfx[4] = {'@', '(', '#', ')'};
- char NEWS_VERSION[] = news_version;
-
-
- pathinit() {
- #ifdef HOME
- /* Relative to the home directory of user HOME */
- sprintf(SPOOL, "%s/%s", logdir(HOME), SPOOLDIR");
- sprintf(LIB, "%s/%s", logdir(HOME), LIBDIR");
- #endif
- if (strlen(LIB) >= FPATHLEN-15)
- xerror("LIB too long");
- if (strlen(SPOOL) > FPATHLEN)
- xerror("SPOOL too long");
- #if defined(HOME) && !defined(SENDMAIL)
- sprintf(MAILPARSER, "%s/recmail", LIB);
- #endif
- #ifndef MYNAME
- #ifdef UNAME
- {
- struct utsname ubuf;
- uname(&ubuf);
- strcpy(FULLSYSNAME, ubuf.nodename);
- }
- #else
- #ifdef GHNAME
- gethostname(FULLSYSNAME, sizeof FULLSYSNAME);
- #else
- whoami();
- #endif GHNAME
- #endif UNAME
- #endif MYNAME
- }
-
-
- #if !defined(UNAME) && !defined(GHNAME) && !defined(MYNAME)
- #define HDRFILE "/usr/include/whoami.h"
-
- whoami()
- {
- char buf[BUFSIZ];
- FILE *fd;
-
- fd = fopen(HDRFILE, "r");
- if (fd == NULL) {
- fprintf(stderr, "Cannot open %s\n", HDRFILE);
- exit(1);
- }
-
- for (;;) { /* each line in the file */
- if (fgets(buf, sizeof buf, fd) == NULL) {
- fprintf(stderr, "no sysname in %s\n", HDRFILE);
- fclose(fd);
- exit(2);
- }
- if (sscanf(buf, "#define sysname \"%[^\"]\"", FULLSYSNAME) == 1) {
- fclose(fd);
- return;
- }
- }
- }
- #endif
- !E!O!F!
-
- cat > lib/ndir.h <<\!E!O!F!
- #if BSDREL >= 42
- #include <sys/dir.h>
- #else
-
- #if defined(pdp11) || USGREL == 30
- #define DIRBLKSIZ 512
- #else
- #define DIRBLKSIZ 1024
- #endif
-
- struct direct {
- long d_ino; /* inode number of entry */
- short d_namlen; /* length of string in d_name */
- char d_name[16]; /* name must be no longer than this */
- };
-
- /*
- * Definitions for library routines operating on directories.
- */
- typedef struct {
- int dd_fd;
- int dd_nleft;
- char *dd_nextc;
- char dd_buf[DIRBLKSIZ];
- } DIR;
-
- #ifndef NULL
- #define NULL 0
- #endif
- extern DIR *opendir();
- extern struct direct *readdir();
- extern void closedir();
- #endif
- !E!O!F!
-
- cat > lib/newer.c <<\!E!O!F!
- /*
- * Program to determine whether file2 needs to be updated from file1.
- * that another one. Usage: newer file1 file2
- * Returns:
- * 1 file2 is newer than file1.
- * 0 file2 is older than file1 or one of the files does not exist.
- * 8 arg count.
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
-
- main(argc, argv)
- char **argv ;
- {
- struct stat st1, st2;
-
- if (argc != 3) {
- fputs("Usage: newer file1 file2\n", stderr);
- exit(8);
- }
- if (stat(argv[1], &st1) < 0) {
- fputs("newer: can't stat ", stderr);
- fputs(argv[1], stderr);
- fputs("\n", stderr);
- exit(0); /* force update attempt */
- }
- if (stat(argv[2], &st2) < 0 || st2.st_mtime < st1.st_mtime)
- exit(0);
- exit(1); /* up to date */
- }
- !E!O!F!
-
- cat > lib/newsrc.doc <<\!E!O!F!
- 1. FORMAT OF .NEWSRC FILE
-
- Since the .newsrc file is shared between a number of news reading
- programs, care should be taken to allow for the evolution of this file.
- Lines in the file fall into several types.
-
- 1) Newsgroups lines.
-
- A newsgroup line consists of a newsgroup name, followed by subscription
- indication, followed by a flags field, followed by a list of article
- numbers. A line should not be considered to be a newsgroup line unless
- the first character of the line is a lowercase letter and the
- subscription indication immediately follows the newsgroup name.
-
- The subscription indication consists of a ':' to indicate that the user
- subscribes to this group, or an '!' to indicate that the user does not
- subscribe to this group.
-
- The flags field is currently unused but is reserved for future use. It
- consists of a word not beginning with a digit, and terminated by a
- space.
-
- The list of article numbers should not have any spaces in it. It
- consists of a comma separated list of articles which have been read. A
- range of articles may be indicated by two numbers separated by a minus
- sign.
-
- Ideally, newsgroups should be presented in the order in which they
- appear in the .newsrc file, and newsgroups not appearing in the .newsrc
- file should be shown last. At any rate, the order of newsgroups in
- the .newrc file should not be disturbed.
-
- The crash recovery code writes updated lines to the end of the .newsrc
- file as they are modified. Therefore, the last entry in the .newsrc
- file should be believed. However, the first occurence of a newsgroup
- in the .newsrc file gives it's display position.
-
- 2) Unsubscribed discussions.
-
- Any line beginning with a '<' contains a message-ID of a discussion
- which has been unsubscribed to. Followups to such articles should not
- be shown.
-
- 3) Comment lines.
-
- All other lines should be treated as comment lines. When the .newsrc
- file is rewritten, comment lines should be output first. 2.10 deletes
- certain comment lines; this is unacceptable.
- !E!O!F!
-
- cat > lib/newsrc.h <<\!E!O!F!
- #define MAXUNSUB 200 /* max number discussion unsubscribed from */
- #define MAXRCJUNK 128 /* maximum number of comment lines */
-
- #define NG_UNSUB 01
-
- struct ngentry { /* newsgroup entry */
- char *ng_name; /* name of newsgroup */
- char *ng_bits; /* which articles have been read */
- struct ngentry *ng_next;/* next newgroup in .newsrc order */
- char ng_unsub; /* set if we have unsubscribed */
- };
-
- #define ng_num(ngp) ((ngp) - ngtable)
- #define numtong(num) (&ngtable[num])
- #ifdef DEBUG
- #define isunread(i) (i > 0 && i <= maxartno ? _isunread(i) : abort())
- #define clrunread(i) (i > 0 && i <= maxartno ? _clrunread(i) : abort())
- #define setunread(i) (i > 0 && i <= maxartno ? _setunread(i) : abort())
- #define _isunread(i) (bitmap[(i-1) >> 3] & (1 << (i-1) % 8))
- #define _setunread(i) (bitmap[(i-1) >> 3] |= (1 << (i-1) % 8))
- #define _clrunread(i) (bitmap[(i-1) >> 3] &= ~(1 << (i-1) % 8))
- #else
- #define isunread(i) (bitmap[(i-1) >> 3] & (1 << (i-1) % 8))
- #define setunread(i) (bitmap[(i-1) >> 3] |= (1 << (i-1) % 8))
- #define clrunread(i) (bitmap[(i-1) >> 3] &= ~(1 << (i-1) % 8))
- #endif
-
-
- struct ngentry *findgroup();
- struct ngentry *prevgrp(), *nextgrp();
-
-
- extern struct ngentry ngtable[MAXGROUPS];
- extern struct ngentry *curng, *firstng, *lastng;
- extern int ndunsub;
- extern long dunsub[MAXUNSUB];
- extern char *rcjunk[MAXRCJUNK];
- extern char **nextrcjunk;
- extern int minartno;
- extern int maxartno;
- extern char *bitmap;
- !E!O!F!
-
- cat > lib/nextgrp.c <<\!E!O!F!
- #include <stdio.h>
- #include "defs.h"
- #include "newsrc.h"
-
-
- struct ngentry *
- nextgrp(ngp)
- struct ngentry *ngp;
- {
- if (ngp == NULL)
- return firstng;
- else
- return ngp->ng_next;
- }
- !E!O!F!
-
- cat > lib/ng.h <<\!E!O!F!
- #define MAXNGNAME 32
-
- #define G_MOD 01 /* indicates moderated or fa.all group */
-
- struct ngrec {
- char g_name[MAXNGNAME]; /* newsgroup name */
- short g_num; /* newsgroup number */
- short g_flags; /* various flags */
- } ;
-
- extern int maxng; /* max value for g_num */
- extern FILE *ngfp;
-
- #define ALL_GROUPS(ngrec) for (nginit() ; ngread(&(ngrec)) ; )
- !E!O!F!
-
- cat > lib/ngchain.c <<\!E!O!F!
- /*
- * Routines step through all the elements of a newsgroup.
- * Called by the BNG macro.
- */
-
- #include <stdio.h>
- #include "af.h"
-
-
- DPTR nglnext ;
-
-
- DPTR
- nglfirst(ngnum) {
- return nglnext = readptr(ngchain(ngnum)) ;
- }
-
-
- ARTNO
- ngltest(ngnum, a)
- int ngnum ;
- struct artrec *a ;
- {
- register int i ;
-
- if (nglnext == DNULL)
- return -1 ;
- readrec(nglnext, a) ;
- for (i = 0 ; i < a->a_ngroups ; i++) {
- if (a->a_group[i].a_ngnum == ngnum) {
- nglnext = a->a_group[i].a_ngchain ;
- return a->a_group[i].a_artno ;
- }
- }
- xerror("bad newsgroup chain") ;
- }
- !E!O!F!
-
- cat > lib/ngmatch.c <<\!E!O!F!
- #include "defs.h"
-
- /*
- * News group matching.
- *
- * nglist is a list of newsgroups.
- * sublist is a list of subscriptions.
- * sublist may have "meta newsgroups" in it.
- * All fields are NGDELIM separated,
- *
- * Currently implemented glitches:
- * sublist uses 'all' like shell uses '*', and '.' like shell '/'.
- * If subscription X matches Y, it also matches Y.anything.
- */
- ngmatch(nglist, sublist)
- register char *nglist, *sublist;
- {
- register char *n, *s;
- register int rc;
-
- rc = 0;
- for (n = nglist; *n != '\0' && rc == 0;) {
- for (s = sublist; *s != '\0';) {
- if (*s != NEGCHAR)
- rc |= ptrncmp(s, n);
- else
- rc &= ~ptrncmp(s+1, n);
- while (*s && *s++ != NGDELIM);
- }
- while (*n && *n++ != NGDELIM);
- }
- return(rc);
- }
-
- /*
- * Compare two newsgroups for equality.
- * The first one may be a "meta" newsgroup.
- */
- ptrncmp(ng1, ng2)
- register char *ng1, *ng2;
- {
- while (*ng1 && *ng1 != NGDELIM) {
- if (ng1[0]=='a' && ng1[1]=='l' && ng1[2]=='l') {
- ng1 += 3;
- while (*ng2 && *ng2 != NGDELIM && *ng2 != '.')
- if (ptrncmp(ng1, ng2++))
- return(1);
- return (ptrncmp(ng1, ng2));
- } else if (*ng1++ != *ng2++)
- return(0);
- }
- return (*ng2 == '\0' || *ng2 == '.' || *ng2 == NGDELIM);
- }
- !E!O!F!
-
- cat > lib/nsavestr.c <<\!E!O!F!
- /*
- * Make a copy of a string. The copy cannot be freed.
- */
-
- #include "str.h"
-
- #define BLOCKSIZE 1024
-
- static char *savearea;
- static char *savep;
-
- char *
- nsavestr(s)
- char *s ;
- {
- int size = strlen(s) + 1;
- char *p ;
- char *ckmalloc() ;
-
- if (size > BLOCKSIZE)
- return savestr(s) ;
- if (savearea == 0 || savearea + BLOCKSIZE - savep < size) {
- nsaveclean() ;
- savearea = savep = ckmalloc(BLOCKSIZE) ;
- }
- scopy(s, p = savep) ;
- savep += size ;
- return p ;
- }
-
-
- /*
- * Release unused storage.
- */
-
- nsaveclean() {
- char *realloc() ;
- if (savearea) {
- if (realloc(savearea, savep - savearea) != savearea)
- xerror("realloc blew it") ;
- }
- savearea = 0 ;
- }
- !E!O!F!
-
- cat > lib/nstrip.c <<\!E!O!F!
- /*
- * Strip trailing newlines, blanks, and tabs from 's'.
- * Return 1 if newline was found, else 0.
- */
- nstrip(s)
- register char *s;
- {
- register char *p;
- register int rc;
-
- rc = 0;
- p = s;
- while (*p)
- if (*p++ == '\n')
- rc = 1;
- while (--p >= s && (*p == '\n' || *p == ' ' || *p == '\t'));
- *++p = '\0';
- return(rc);
- }
- !E!O!F!
-
- cat > lib/openrc.c <<\!E!O!F!
- /*
- * Open the .newsrc file, creating it if necessary.
- */
-
- #include <stdio.h>
- #include "defs.h"
- #include "libextern.h"
-
- char newsrc[64] ;
-
- FILE *
- openrc() {
- register char *myrc ;
- register FILE *rcfp ;
- static char READ[] = "r" ;
- char *getenv() ;
-
- if ((myrc = getenv("NEWSRC")) != NULL)
- strcpy(newsrc, myrc);
- else
- sprintf(newsrc, "%s/%s", userhome, NEWSRC);
- if ((rcfp = fopen(newsrc, READ)) == NULL) {
- newrc() ;
- if ((rcfp = fopen(newsrc, READ)) == NULL)
- xerror("Can't create .newsrc file") ;
- }
- return rcfp ;
- }
-
-
- newrc()
- {
- register FILE *fp;
- char users[FPATHLEN];
-
- if (close(creat(newsrc, 0666))) {
- xerror("Cannot create %s", newsrc);
- }
-
- sprintf(users, "%s/users", LIB);
- if ((fp = fopen(users, "a")) != NULL) {
- fprintf(fp, "%s\n", username);
- fclose(fp);
- chmod(users, 0666);
- }
- }
- !E!O!F!
-
- cat > lib/pgetuser.c <<\!E!O!F!
- /*
- * Get user name and home directory. This version always goes to the
- * password file, so it cannot be subverted by modifying the environment.
- */
-
- #include <stdio.h>
- #include <pwd.h>
-
- char *username, *userhome;
-
- pgetuser()
- {
- register struct passwd *p;
- char *savestr();
- struct passwd *getpwuid();
-
- if ((p = getpwuid(getuid())) == NULL)
- xerror("Cannot get user's name");
- username = savestr(p->pw_name);
- userhome = savestr(p->pw_dir);
- }
- !E!O!F!
-
- cat > lib/prefix.c <<\!E!O!F!
- int
- prefix(full, pref)
- register char *full, *pref ;
- {
- register char c ;
-
- while ((c = *pref++) != '\0')
- if (*full++ != c)
- return 0 ;
- return 1 ;
- }
- !E!O!F!
-
- cat > lib/prevgrp.c <<\!E!O!F!
- #include <stdio.h>
- #include "defs.h"
- #include "newsrc.h"
-
-
- struct ngentry *
- prevgrp(ngp)
- struct ngentry *ngp;
- {
- register struct ngentry *p;
-
- if (ngp == NULL)
- return NULL;
- for (p = ngtable ; p->ng_next != ngp ; p++)
- if (p >= ngtable + MAXGROUPS - 1)
- return NULL;
- return p;
- }
- !E!O!F!
-
- cat > lib/process.c <<\!E!O!F!
- /*
- * process - process options for readnews
- */
-
- static char *SccsId = "%W% %G%";
-
- #include <stdio.h>
- #include <ctype.h>
- #include "roptions.h"
- #define TRUE 1
- #define FALSE 0
-
- int mode = UNKNOWN;
-
-
- procopt(argv)
- register char **argv;
- {
- register int state = OPTION;
- register char *p;
- register struct optable *optpt;
- extern char *progname;
- char *savestr(), *realloc();
-
- /* loop once per arg. */
-
- while (*argv != NULL) {
- if (state == OPTION) {
- if (**argv != '-') {
- xerror("Bad option string \"%s\"", *argv);
- }
- while (*++*argv != '\0') {
- for (optpt = options; optpt->optlet != '\0'; ++optpt) {
- if (optpt->optlet == **argv)
- goto found;
- }
- /* unknown option letter */
- fprintf(stderr, "Usage: %s [ -a [ date ]] [ -n newsgroups ] [ -t titles ] [ -lprxhfuM ]\n", progname);
- fprintf(stderr, "\t[ -c [ ``mailer'' ]]\n\n");
- fprintf(stderr, " %s -s\n", progname);
- exit(1);
-
- found:;
- if (mode != UNKNOWN && (mode&optpt->oldmode) == 0) {
- xerror("Bad %c option", **argv);
- }
- if (mode == UNKNOWN)
- mode = optpt->newmode;
- optpt->flag = TRUE;
- state = optpt->newstate;
- }
-
- argv++; /* done with this option arg. */
-
- } else {
-
- /*
- * Pick up a piece of a string and put it into
- * the appropriate buffer.
- */
- if (**argv == '-') {
- state = OPTION;
- continue;
- }
-
- p = optpt->buf;
- if (state == STRING) {
- if (optpt->buf != NULL)
- free(optpt->buf);
- optpt->buf = savestr(*argv);
- state++;
- } else {
- if ((p = realloc(p, strlen(p) + strlen(*argv) + 2)) == NULL)
- xerror("No space");
- optpt->buf = p;
- while (*p) p++;
- *p++ = optpt->filchar;
- strcpy(p, *argv);
- }
- argv++;
- }
- }
-
- /*
- * At this point, we are done with vanilla flag processing.
- * Now deal with defaults and upward compatibility stuff.
- */
- return;
- }
-
-
- /*
- * Process a string containing options. The string is broken up into
- * space separated options and then passed to procopt.
- */
-
- #define MAXOPTS 63
-
- procostr(rcbuf)
- char *rcbuf;
- {
- register char *ptr;
- char *rcline[MAXOPTS + 1];
- int line = -1;
-
- strcat(rcbuf, " \1");
- ptr = rcbuf;
- while (*++ptr)
- if (isspace(*ptr))
- *ptr = '\0';
- for (ptr = rcbuf; ; ptr++) {
- if (!*ptr)
- continue;
- if (*ptr == '\1')
- break;
- if (++line >= MAXOPTS)
- xerror("Too many options");
- rcline[line] = ptr;
- while (*ptr)
- ptr++;
- }
- rcline[++line] = NULL;
- procopt(rcline);
- }
- !E!O!F!
-
- cat > lib/read.c <<\!E!O!F!
- #include <stdio.h>
- #include "af.h"
- #include "libextern.h" /* defines bfr */
-
- long lseek() ;
-
-
- /*
- * Read in an article record.
- */
-
- readrec(dp, a)
- DPTR dp ;
- struct artrec *a ;
- {
- register int len ;
- int i ;
- register char *p ;
- register char *q ;
- char **pp ;
-
- /*printf("readrec %ld\n", (long)dp) ; /*DEBUG*/
- if (lseek(affd, (long)dp, 0) < 0)
- xerror("seek %ld failed, readrec\n", dp) ;
- len = BSIZE - ((int)dp & (BSIZE - 1)) ;
- if (len <= 1 + A_WRTLEN + MAXNG * sizeof(struct artgroup))
- #if BSIZE == 512
- len += BSIZE ;
- #else
- len = 1 + sizeof(struct artrec) ;
- #endif
- if ((len = read(affd, bfr, len)) < 1 + A_WRTLEN + MAXNG * sizeof(struct artgroup)) {
- printf("read returned %d\n", len) ;
- xerror("Bad read in readrec, %ld", dp) ;
- }
- if (bfr[0] != (char)A_PREFIX) {
- printf("len=%d, dp=%ld\n", len, (long)dp);
- fprintf(stderr, "bfr: %o %o %o %o %o\n", bfr[0], bfr[1],
- bfr[2], bfr[3], bfr[4]);
- fprintf(stderr, "A_PREFIX = %o, (char)A_PREFIX = %o\n", A_PREFIX, (char)A_PREFIX);
- xerror("bad article pointer %ld", dp) ;
- }
- bcopy(bfr + 1, (char *)a, A_WRTLEN) ;
- bcopy(bfr + 1 + A_WRTLEN, (char *)a->a_group, i = a->a_ngroups * sizeof(*a->a_group)) ;
- pp = &a->a_ident ;
- p = bfr + 1 + A_WRTLEN + i ;
- q = a->a_space ;
- len -= 1 + A_WRTLEN + i ;
- i = (a->a_flags & A_DUMMY)? 1 : 4 + a->a_nkwords ;
- while (--i >= 0) {
- *pp++ = q ;
- do if (--len < 0) {
- read(affd, bfr, 512) ;
- len = 512 ;
- p = bfr ;
- }
- while (*q++ = *p++) ;
- }
- }
-
-
-
- /*
- * Read a pointer from the article file
- */
-
- DPTR
- readptr(dp)
- DPTR dp ;
- {
- DPTR new ;
-
- if (lseek(affd, (long)dp, 0) < 0)
- xerror("seek %ld failed, readptr\n", dp) ;
- if (read(affd, (char *)&new, sizeof(new)) != sizeof(new))
- xerror("read failed, readptr(%ld)\n", dp) ;
- return new ;
- }
- !E!O!F!
-
- cat > lib/readinrc.c <<\!E!O!F!
- /*
- * Read in the .newsrc file and the newsgroups file. If rcfp is NULL,
- * only the newsgroups file is read.
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <ctype.h>
- #include "defs.h"
- #include "artfile.h"
- #include "ng.h"
- #include "newsrc.h"
- #include "libextern.h"
- #include "str.h"
-
- static int rcmode; /* file modes for .newsrc file */
- int rcreadok; /* .newsrc file has been read */
- int rcsaved; /* .newsrc file has been backed up */
- char *rcjunk[MAXRCJUNK]; /* comment lines in .newsrc file */
- char **nextrcjunk = rcjunk; /* first unused entry in rcjunk */
- struct ngentry ngtable[MAXGROUPS]; /* newsgroup table */
- int ndunsub; /* number of discussions unsubscribed to */
- DPTR dunsub[MAXUNSUB]; /* discussions unsubscribed to */
- struct ngentry *firstng, *lastng; /* articles in .newsrc file */
- struct ngentry *curng; /* current newsgroup */
-
- struct ngentry **nghashtab, *hashng();
-
-
- readinrc(rcfp)
- FILE *rcfp;
- {
- register struct ngentry *ngp;
- register char *p;
- char unsub;
- int i;
- DPTR dp;
- struct artrec a;
- struct ngrec g;
- struct stat statb;
-
- gfopen();
- if (maxng >= MAXGROUPS)
- xerror("Too many groups, increase MAXGROUPS");
- nghashtab = ckmalloc(i = (MAXGROUPS * 2 + 1) * sizeof *nghashtab);
- bzero((char *)nghashtab, i);
- ALL_GROUPS(g) {
- ngtable[g.g_num].ng_name = nsavestr(g.g_name);
- hashng(g.g_name, &ngtable[g.g_num]);
- }
- gfclose();
- if (rcfp == NULL)
- goto out;
- if (fstat(fileno(rcfp), &statb) >= 0)
- rcmode = statb.st_mode;
- while (fgets(bfr, LBUFLEN, rcfp) != NULL) {
- if (!nstrip(bfr))
- xerror(".newsrc line too long");
- if (bfr[0] == '<') {
- char ident[NAMELEN];
- scopyn(bfr, ident, NAMELEN);
- if (ndunsub >= MAXUNSUB)
- xerror("Unsubscribed to too many discussions");
- if ((dp = lookart(ident, &a)) != DNULL)
- dunsub[ndunsub++] = dp;
- } else if (islower(bfr[0])) { /* newsgroup line? */
- for (p = bfr ; *p != ':' && *p != '!' ; p++)
- if (*p == '\0' || *p == ' ' || *p == '\t')
- goto junk;
- unsub = (*p == '!');
- *p++ = '\0';
- if (*p == ' ')
- p++;
- ngp = hashng(bfr, (struct ngentry *)0);
- if (ngp != NULL) {
- if (ngp->ng_bits != NULL) {
- free(ngp->ng_bits);
- } else {
- addrc(ngp);
- }
- ngp->ng_bits = savestr(p);
- ngp->ng_unsub = unsub;
- }
- } else {
- junk: if (nextrcjunk >= &rcjunk[MAXRCJUNK])
- xerror("Too many lines in .newsrc");
- *nextrcjunk++ = savestr(bfr);
- }
- }
- free(nghashtab);
- rcreadok = 1;
-
- out:
- /* add new groups to the .newsrc file */
- for (ngp = ngtable ; ngp < ngtable + MAXGROUPS ; ngp++) {
- if (ngp->ng_name != NULL && ngp->ng_bits == NULL && wewant(ngp->ng_name))
- addrc(ngp);
- }
- }
-
-
-
- /*
- * Write out the .newsrc file.
- */
- writeoutrc()
- {
- FILE *rcfp;
- register int i;
- char **jp;
- struct ngentry *ngp;
- char newstmp[FPATHLEN];
- char newsbak[FPATHLEN];
- struct artrec a;
- FILE *ckfopen();
-
- if (!rcreadok)
- return;
- updaterc();
- sprintf(newstmp, "%s.tmp", newsrc);
- rcfp = ckfopen(newstmp, "w");
- if (rcmode)
- chmod(newstmp, rcmode);
-
- /* Write out options line, continuations, and comments. */
- for (jp = rcjunk ; jp < nextrcjunk ; jp++)
- fprintf(rcfp, "%s\n", *jp);
-
- /* Write out the newsgroup lines. */
- for (ngp = firstng ; ngp != NULL ; ngp = ngp->ng_next) {
- fprintf(rcfp, "%s%c", ngp->ng_name, ngp->ng_unsub? '!' : ':');
- if (ngp->ng_bits != NULL && *ngp->ng_bits != '\0')
- fprintf(rcfp, " %s", ngp->ng_bits);
- putc('\n', rcfp);
- }
- /* write out a list of discussions we have unsubscribed to */
- for (i = 0 ; i < ndunsub ; i++) {
- readrec(dunsub[i], &a);
- fprintf(rcfp, "%s\n", a.a_ident);
- }
- if (ferror(rcfp) || fclose(rcfp) == EOF)
- xerror("write error on .newsrc.tmp");
- sprintf(newsbak, "%s.bak", newsrc);
- if (! rcsaved) {
- rename(newsrc, newsbak);
- rcsaved++;
- }
- if (rename(newstmp, newsrc) < 0)
- xerror("rename .newsrc.tmp to .newsrc failed");
- }
-
-
- struct ngentry *
- hashng(name, entry)
- char *name;
- struct ngentry *entry;
- {
- register char *p;
- register int i;
- register struct ngentry *ngp;
-
- i = 0;
- for (p = name ; *p ; i += *p++);
- if (p > name + 2)
- i += (p[-2] << 2) + (p[-1] << 1);
- i &= 077777; /* protect against negetive chars */
- for (i = i % (MAXGROUPS * 2 + 1) ; (ngp = nghashtab[i]) != NULL ; ) {
- if (strcmp(ngp->ng_name, name) == 0)
- return ngp;
- if (++i >= (MAXGROUPS * 2 + 1))
- i = 0;
- }
- if (entry != NULL)
- nghashtab[i] = entry;
- return ngp;
- }
- !E!O!F!
-
- cat > lib/rename.c <<\!E!O!F!
- #include <errno.h>
- #include "config.h"
-
- #if BSDREL < 42
-
- int
- rename(from, to)
- char *from, *to ;
- {
- extern int errno ;
-
- if (link(from, to) < 0) {
- if (errno != EEXIST)
- return -1 ;
- if (unlink(to) < 0 || link(from, to) < 0)
- return -1 ;
- }
- return unlink(from) ;
- }
-
- #endif
- !E!O!F!
-
- cat > lib/replyname.c <<\!E!O!F!
- /*
- * Generate an address for replying to this article
- */
-
- #include <stdio.h>
- #include "config.h"
- #include "defs.h"
- #include <sys/types.h>
- #include "arthead.h"
-
- char *
- replyname(hptr, tbuf)
- struct arthead *hptr;
- char tbuf[PATHLEN];
- {
- register char *ptr;
- extern char FULLSYSNAME[];
- char *getaddr();
-
- #ifndef INTERNET
- strcpy(tbuf, hptr->h_path);
- /*
- * Play games stripping off multiple berknet
- * addresses (a!b!c:d:e => a!b!d:e) here.
- */
- for (ptr=tbuf; *ptr; ptr++)
- if (index(NETCHRS, *ptr) && *ptr == ':' && index(ptr+1, ':'))
- strcpy(ptr, index(ptr+1, ':'));
- #else
- ptr = hptr->h_from;
- if (hset(hptr->h_replyto))
- ptr = hptr->h_replyto;
- getaddr(ptr, tbuf);
- #endif
- return tbuf;
- }
- !E!O!F!
-
- cat > lib/rewinddir.c <<\!E!O!F!
- #include "config.h"
- #if BSDREL < 42
- #include <sys/types.h>
- #include <sys/param.h>
- #include "ndir.h"
-
- /*
- * Go back to the beginning of a directory.
- */
-
- rewinddir(dirp)
- DIR *dirp;
- {
- dirp->dd_nleft = 0;
- lseek(dirp->dd_fd, 0L, 0);
- }
- #endif
- !E!O!F!
-
- cat > lib/rmnf.c <<\!E!O!F!
- /*
- * Zap the notesfile indicator.
- */
-
- #define equal(s1, s2) (strcmp(s1, s2) == 0)
-
- rmnf(title)
- char *title ;
- {
- register char *p ;
-
- p = title + strlen(title) - 7 ;
- if (p > title && equal(p, " - (nf)")) {
- *p = '\0' ;
- return 1 ;
- }
- return 0 ;
- }
- !E!O!F!
-
- cat > lib/roptions.c <<\!E!O!F!
- #include <stdio.h>
- #include "config.h"
- #include "defs.h"
- #include "roptions.h"
-
-
- char *savestr(), *getenv(), *index(), *hfgets();
-
-
- struct optable options[] = { /*
- optlet filchar flag newstate oldmode newmode buf */
- 'p', '\0', FALSE, OPTION, UNKNOWN, UNKNOWN,NULL,
- 't', '\1', FALSE, STRING, ANY, UNKNOWN,NULL,
- 'a', ' ', FALSE, STRING, ANY, UNKNOWN,NULL,
- 'n', NGDELIM, FALSE, STRING, ANY, UNKNOWN,NULL,
- 'c', ' ', FALSE, STRING, UNKNOWN, UNKNOWN,NULL,
- 'l', ' ', FALSE, OPTION, UNKNOWN, UNKNOWN,NULL,
- 'r', '\0', FALSE, OPTION, ANY, UNKNOWN,NULL,
- /* the s option used to read a list of newsgroups. Not any more */
- 's', NGDELIM, FALSE, OPTION, ANY, UNKNOWN,NULL,
- 'x', '\0', FALSE, OPTION, ANY, UNKNOWN,NULL,
- 'h', '\0', FALSE, OPTION, ANY, UNKNOWN,NULL,
- 'M', '\0', FALSE, OPTION, UNKNOWN, MAIL, NULL,
- 'f', '\0', FALSE, OPTION, ANY, UNKNOWN,NULL,
- 'u', '\0', FALSE, OPTION, ANY, UNKNOWN,NULL,
- 'e', '\0', FALSE, OPTION, ANY, UNKNOWN,NULL,
- '1', '\0', FALSE, OPTION, ANY, UNKNOWN,NULL,
- '2', '\0', FALSE, OPTION, ANY, UNKNOWN,NULL,
- 'A', '\0', FALSE, OPTION, ANY, UNKNOWN,NULL,
- '\0', '\0', 0, 0, 0, 0, NULL
- };
-
- char *progname ;
- char *titles[10] ; /* list of titles */
- extern char bfr[] ;
-
-
- roptions(argv, rcfp)
- char **argv ;
- FILE *rcfp ;
- {
- char *p ;
- char **pp ;
-
- progname = *argv++ ;
- if ((p = getenv("NEWSOPTS")) != NULL) {
- scopyn(p, bfr, LBUFLEN - 2) ;
- procostr(bfr) ;
- }
- if (rcfp != NULL && hfgets(bfr, LBUFLEN - 2, rcfp) != NULL && prefix(bfr, "options ")) {
- procostr(bfr + 8) ;
- }
- if (sublist == NULL)
- sublist = savestr(DFLTSUB);
- #ifdef ADMSUB
- sprintf(bfr, "%s,%s", sublist, ADMSUB);
- free(sublist);
- sublist = savestr(bfr);
- #endif
-
- procopt(argv) ;
-
- if (cflag) {
- oneflag = FALSE;
- twoflag = TRUE;
- }
- if (pflag) {
- oneflag = FALSE;
- twoflag = FALSE;
- }
- if (!oneflag && !twoflag && !pflag) {
- oneflag = TRUE;
- twoflag = TRUE;
- }
- if (oneflag && !twoflag)
- cflag = 1;
- strcpy(bfr, sublist);
- makehimask(bfr, "junk");
- makehimask(bfr, "control");
- /* makehimask(bfr, "test"); */
- free(sublist);
- sublist = savestr(bfr);
- if (toptbuf) {
- pp = titles ;
- p = toptbuf ;
- for (;;) {
- if (pp >= titles + 9)
- xerror("Too many titles") ;
- *pp++ = p ;
- if ((p = index(p, '\1')) == NULL)
- break ;
- *p++ = '\0' ;
- }
- }
- }
- !E!O!F!
-
- cat > lib/roptions.h <<\!E!O!F!
- /* flags for readnews */
- #define pflag options[0].flag
- #define tflag options[1].flag
- #define toptbuf options[1].buf
- #define aflag options[2].flag
- #define datebuf options[2].buf
- #define nflag options[3].flag
- #define sublist options[3].buf
- #define cflag options[4].flag
- #define coptbuf options[4].buf
- #define lflag options[5].flag
- #define rflag options[6].flag
- #define sflag options[7].flag
- #define xflag options[8].flag
- #define hflag options[9].flag
- #define Mflag options[10].flag
- #define fflag options[11].flag
- #define uflag options[12].flag
- #define eflag options[13].flag
- #define oneflag options[14].flag
- #define twoflag options[15].flag
- #define Aflag options[16].flag
-
- #define UNKNOWN 0001 /* possible modes for news program */
- #define MAIL 0004
- #define ANY 0007
-
- #define OPTION 0 /* pick up an option string */
- #define STRING 1 /* pick up a string of arguments */
-
- struct optable { /* options table. */
- char optlet; /* option character. */
- char filchar; /* if to pickup string, fill character. */
- int flag; /* TRUE if have seen this opt. */
- int newstate; /* STRING if takes arg, else OPTION */
- int oldmode; /* OR of legal input modes. */
- int newmode; /* output mode. */
- char *buf; /* string buffer */
- };
-
- extern struct optable options[];
- extern int mode;
- !E!O!F!
-
- cat > lib/savestr.c <<\!E!O!F!
- /*
- * Make a copy of a string
- */
-
- char
- *savestr(s)
- char *s ;
- {
- char *p ;
- char *ckmalloc() ;
-
- p = ckmalloc(strlen(s) + 1) ;
- strcpy(p, s) ;
- return p ;
- }
- !E!O!F!
-
- cat > lib/schar.c <<\!E!O!F!
- /*
- * Convert a character to an integer, performing sign extension even on
- * machines that don't provide hardware support for signed characters.
- * This routine should be replaced by the macro
- * #define schar(c) ((char)(c))
- * for compilers that support signed characters.
- */
-
- /* The high bit of a character */
- #define SIGNBIT (int)((unsigned char)(-1) &~ ((unsigned char)(-1) >> 1))
- #define EXTBITS (int)(-1 &~ (unsigned char)(-1))
-
- int
- schar(c)
- char c ;
- {
- return (c & SIGNBIT) ? c | EXTBITS : c ;
- }
- !E!O!F!
-
- cat > lib/scopyn.c <<\!E!O!F!
- scopyn(from, to, n)
- register char *from, *to ;
- register int n ;
- {
- while (--n > 0 && (*to++ = *from++) != '\0') ;
- *to = '\0' ;
- }
- !E!O!F!
-
- cat > lib/scopyn.pdp <<\!E!O!F!
- / SCOPYN(FROM, TO, N) CHAR *FROM, *TO;
- /
- / Copy string "from" to string "to", truncating "to" to n - 1
- / characters to avoid overflow.
- /
-
- .globl _scopyn
-
- _scopyn:
- mov sp, r0 / prepare to access args
- mov r2, -(sp) / save r2
- tst (r0)+ /
- mov (r0)+, r1 / get from
- mov (r0)+, r2 / get to
- mov (r0)+, r0 / get n
- br 2f / enter middle of loop
- 1: movb (r1)+, (r2)+ / copy a byte
- beq 3f / until a nul is encountered
- 2: sob r0, 1b / or count is exhausted
- 3: clrb (r2) / nul terminate "to" string
- mov (sp)+, r2 / restore r2
- rts pc / and return
- !E!O!F!
-
- cat > lib/scopyn.u3b <<\!E!O!F!
- .file "scopyn.u3b" # give me a break!
- .globl scopyn
- .align 4
- scopyn: save &1 # save r8
- movw 0(%ap), %r0 # get from
- movw 4(%ap), %r1 # get to
- subw3 &1, 8(%ap), %r2 # get count - 1 to leave room for nul
- movw &0, %r8 # string terminator
- movcce %r0, %r2, %r1, %r8 # copy the string
- movb &0, 0(%r1) # append nul terminator
- ret &1 # and return
- !E!O!F!
-
- cat > lib/scopyn.vax <<\!E!O!F!
- # SCOPYN(SRC, DEST, N) CHAR *SRC, *DEST
- #
- # Copy src to dest, truncating the source string to n - 1 charaters
- # if necessary. Dest will always get a nul terminator.
- #
- .globl _scopyn
- .align 2
- _scopyn:.word 0 # no registers saved
- movq 4(ap), r4 # get src and dest
- subl3 $1, 12(ap), r0 # get n, leaving space for nul
- locc $0, r0, (r4) # scan until nul or count exhausted
- subl2 r4, r1 # find length
- movc3 r1, (r4), (r5) # move the characters
- clrb (r3) # nul terminate dest
- ret # and return
- !E!O!F!
-
- cat > lib/setup <<\!E!O!F!
- #!/bin/sh
-
- : This shell procedure reads in the config file, generates defaults for
- : all the values not specified, and generated the config.h, newsdefs.h,
- : makedefs, and archive. It should be run to bring up a new system.
- :
- : This shell procedure uses the value ",,,," to indicate that a variable
- : has not been set.
-
- exec 3<&0
- if test ! -f config
- then echo "Please create config file and run again."
- exit 1
- fi
-
- : figure out who is running this program
- user=${LOGNAME-${USER-,,,,}}
- if test "$user" = ,,,,
- then ls -l config > junk
- exec < junk
- read x y user rest
- rm -f junk
- if test "$user" = ""
- then user=news
- fi
- fi
-
- : look for other setup programs
- setups= special=
- for x in ../*
- do if test -f $x/config.parms
- then setups="$setups $x/setup"
- special="$special`cat $x/config.parms`
- "
- fi
- done
-
- : set up all the defaults
- lib=/usr/lib/news
- spool=/usr/spool/news
- bin=/usr/bin
- admin=,,,,
- compadmin=no
- newsusr=,,,,
- newsgrp=,,,,
- home=,,,,
- sys=,,,,
- cpu=,,,,
- small=,,,,
- umask=000
- dftexp=14
- tmail=,,,,
- mailer=,,,,
- dftsub=all
- admsub=general,all.announce
- page=,,,,
- notify=,,,,
- dfteditor=,,,,
- manually=
- internet=
- mydomain=,,,,
- myname=,,,,
- myorg=,,,,
- sendmail=,,,,
- uname=,,,,
- ghname=,,,,
- v7mail=
- newsrc=.newsrc
- maxgroups=350
- buflen=,,,,
- lbuflen=1024
- pathlen=512
- datelen=48
- namelen=64
- fpathlen=64
- termcap=,,,,
-
- : read in the config file
- exec <config
- while read name value
- do case $name in
- path) PATH=$value ;;
- lib) lib=$value ;;
- spool) spool=$value ;;
- bin) bin=$value ;;
- admin) admin=$value ;;
- compadmin) compadmin=$value ;;
- newsusr) newsusr=$value ;;
- newsgrp) newsgrp=$value ;;
- home) home=$value ;;
- sys) sys=$value ;;
- cpu) cpu=$value ;;
- small) small=$value ;;
- umask) umask=$value ;;
- dftexp) dftexp=$value ;;
- tmail) tmail=$value ;;
- mailer) mailer=$value ;;
- dftsub) dftsub=$value ;;
- dfltsub) dftsub=$value ;;
- admsub) admsub=$value ;;
- page) page=$value ;;
- notify) notify=$value ;;
- dfteditor) dfteditor=$value ;;
- manually) manually=$value ;;
- internet) internet=$value ;;
- mydomain) mydomain=$value ;;
- myname) myname=$value ;;
- myorg) myorg=$value ;;
- uname) uname=$value ;;
- ghname) ghname=$value ;;
- v7mail) v7mail=$value ;;
- newsrc) newsrc=$value ;;
- maxgroups) maxgroups=$value ;;
- buflen) buflen=$value ;;
- lbuflen) lbuflen=$value ;;
- pathlen) pathlen=$value ;;
- datelen) datelen=$value ;;
- namelen) namelen=$value ;;
- fpathlen) fpathlen=$value ;;
- termcap) termcap=$value ;;
- "") ;;
- "#"*) ;;
- *) for x in $special
- do if test "$name" = "$x"
- then name=
- fi
- done
- if test "$name" != ""
- then echo "Unknown config keyword: $name"
- exit 2
- fi
- ;;
- esac
- done
-
- if test "$sys" = ,,,,
- then if test -f /usr/include/termio.h
- then if test -f /bin/shl -o -f /usr/bin/shl
- then sys=sys5r2
- elif test -f /usr/bin/cflow
- then sys=sys5
- else sys=sys3
- fi
- else if test -f /usr/include/sys/time.h
- then sys=4.2bsd
- elif test -d /usr/ucb
- then sys=4.1bsd
- else sys=v7
- fi
- fi
- echo system assumed to be $sys.
- fi
-
- case "$sys" in
- sys3) USGREL=30 BSDREL=6 ;;
- sys5) USGREL=50 BSDREL=6 ;;
- sys5r2) USGREL=52 BSDREL=6 ;;
- v7) BSDREL=7 USGREL=6 ;;
- 4.1bsd) BSDREL=41 USGREL=6 ;;
- 4.2bsd) BSDREL=42 USGREL=6 ;;
- *) echo "Unknown system type $sys"
- exit 1 ;;
- esac
-
- if test "$cpu" = ,,,,
- then cc -P cpu.c
- cpu=`sed -n s/X//p cpu.i`
- /bin/rm -f cpu.i
- fi
- case "$cpu" in
- pdp11|vax|u3b|other) ;;
- "") cpu=other ;;
- *) echo "Unknown cpu type $cpu"
- exit 1
- ;;
- esac
-
- if test "$small" = ,,,, -a $cpu = pdp11
- then small=yes
- fi
- if test "$buflen" = ,,,,
- then if test "$small" = "no" -o "$small" = ,,,,
- then buflen=256
- else buflen=128
- fi
- fi
-
- if test "$uname" = ,,,, -a $USGREL -ge 20
- then uname=yes
- fi
- if test "$ghname" = ,,,, -a $BSDREL -ge 42
- then ghname=yes
- fi
-
- : check all the boolean flags
- for x in manually internet uname ghname v7mail small compadmin
- do eval y=\$$x
- case "$y" in
- no|,,,,)eval $x=,,,, ;;
- ""|yes) eval $x= ;;
- *) echo $x is a boolean flag.
- exit 1 ;;
- esac
- done
-
- : check that all numeric parameters are set and are numbers
- for x in umask dftexp maxgroups buflen lbuflen pathlen datelen namelen fpathlen
- do eval y=\$$x
- case "$y" in
- [0-9]|[0-9][0-9]|[0-9][0-9][0-9]|[0-9][0-9][0-9][0-9]|[0-9][0-9][0-9][0-9][0-9]) ;;
- ,,,,) echo "$x not set"
- exit 1 ;;
- *) echo "$x value should be numeric"
- exit 1 ;;
- esac
- done
-
- : Check that required values are specified
- for x in myorg mydomain newsusr newsgrp
- do eval y=\$$x
- if test "$y" = ,,,,
- then echo $x not set
- exit 1
- fi
- done
-
- case "$mydomain" in
- ""|.*) ;;
- *) echo domain name should begin with a dot.
- exit 1 ;;
- esac
-
- if test "$admin" = ,,,,
- then admin=$user
- fi
- if test "$notify" = ""
- then notify=$admin
- fi
- if test "$termcap" = ,,,,
- then if test -f /usr/lib/libtermcap.a
- then termcap=-ltermcap
- elif test -f /usr/lib/libtermlib.a
- then termcap=-ltermlib
- elif test -f /usr/lib/libcurses.a
- then termcap=-lcurses
- else termcap=-ltermcap
- fi
- fi
- if test "$sendmail" = ,,,,
- then if test -f /usr/lib/sendmail
- then sendmail=/usr/lib/sendmail
- fi
- fi
-
- : on BSD systems, prefer /bin/mail over /usr/ucb/mail
- if test "$mailer" = ,,,, -a -f /bin/mail
- then mailer=/bin/mail
- fi
-
- : do some path searches
- y=
- for x in page more page pg dfteditor vi dfteditor ed mailer mail
- do if test "$y" = ""
- then y=$x
- else eval v=\$$y
- if test "$v" = ,,,,
- then IFS=:
- for z in $PATH
- do if test -f $z/$x
- then eval $y=$z/$x
- break
- fi
- done
- IFS='
- '
- fi
- y=
- fi
- done
-
- if test "$mailer" = ,,,
- then echo Can\'t find mail
- exit 1
- fi
- if test "$dfteditor" = ,,,,
- then echo Can\'t find ed
- exit 1
- fi
-
- for x in admsub page sendmail
- do eval y=\$$x
- if test "$y" = ""
- then eval $x=,,,,
- fi
- done
-
- if test "$compadmin" = ""
- then adminid=,,,,
- else adminid=`sed -n "s/^$admin:[^:]*:\([^:]*\):.*/\1/p" /etc/passwd`
- if test "$adminid" = ""
- then echo Can\'t find $admin in /etc/passwd file.
- exit 1
- fi
- fi
-
- : 2.10.2 moved inews [Grrr!]
- if test -f $lib/inews
- then inews=$lib/inews
- else inews=$bin/inews
- fi
-
- if test $USGREL -ge 30
- then index=strchr
- rindex=strrchr
- usg=
- else index=,,,,
- rindex=,,,,
- usg=,,,,
- fi
-
- grep -v ,,,, > config.h.tmp <<!
- #define USGREL $USGREL
- #define BSDREL $BSDREL
- #define USG$usg
- #define SMALL$small
- #define index $index
- #define rindex $rindex
- !
-
- grep -v ,,,, > newsdefs.h.tmp <<!
- /*
- * newsdefs.h - defines for news related programs.
- *
- * This file is created by the setup program, and should be changed
- * by modifying the entries in config.
- */
-
- #define N_UMASK $umask
- #define DFLTEXP ($dftexp*24L*3600L)
- #define DFTEDITOR "$dfteditor"
- #define DFLTSUB "$dftsub"
- #define ADMSUB "$admsub"
- #define PAGE "$page"
- #define TMAIL "$tmail"
- #define MAILER "$mailer"
- #define INEWS "$inews"
- #define RNEWS "$bin/rnews"
- #define POSTNM "$bin/postnm"
- #define LIBDIR "$lib
- #define SPOOLDIR "$spool
- #define BINDIR "$bin
- #define HOME "$home"
- #define NOTIFY "$notify"
- #define ADMIN "$admin"
- #define ROOTID $adminid
- #define MANUALLY$manually
- #define INTERNET$internet
- #define MYDOMAIN "$mydomain"
- #define MYNAME "$myname"
- #define UNAME$uname
- #define GHNAME$ghname
- #define SENDMAIL "$sendmail"
- #define V7MAIL$v7mail
- #define MYORG "$myorg"
- #define NEWSRC "$newsrc"
- #define MAXGROUPS $maxgroups
- #define BUFLEN $buflen
- #define LBUFLEN $lbuflen
- #define PATHLEN $pathlen
- #define DATELEN $datelen
- #define NAMELEN $namelen
- #define FPATHLEN $fpathlen
- !
-
- if test "$home" != ,,,,
- then hdir=`logdir $home`/
- else hdir=
- fi
-
- grep -v ,,,, > makedefs.tmp <<!
- LIBDIR=$hdir$lib
- SPOOLDIR=$hdir$spool
- BINDIR=$bin
- NEWSUSR=$newsusr
- NEWSGRP=$newsgrp
- HOME=$home
- CPU=$cpu
- USGREL=$USGREL
- BSDREL=$BSDREL
- TERMCAP=$termcap
- !
-
- if cmp -s config.h.tmp config.h
- then /bin/rm config.h.tmp
- else /bin/mv config.h.tmp config.h
- fi
- if cmp -s newsdefs.h.tmp newsdefs.h
- then /bin/rm newsdefs.h.tmp
- else /bin/mv newsdefs.h.tmp newsdefs.h
- fi
- if cmp -s makedefs.tmp makedefs
- then /bin/rm makedefs.tmp
- else /bin/mv makedefs.tmp makedefs
- fi
-
- for x in $setups
- do $x -M
- done
- echo 'The modified time of this file indicates when setup was last run.' > setuptime
-
- sed -e 's/B,,,,/no/' -e 's/B$/yes/' -e '/,,,,/s/^/#/' -e 's/[ ],,,,//' > config.used <<!
- path $PATH
- lib $lib
- spool $spool
- bin $bin
- admin $admin
- compadmin B$compadmin
- newsusr $newsusr
- newsgrp $newsgrp
- home $home
- sys $sys
- cpu $cpu
- small B$small
- umask $umask
- dftexp $dftexp
- tmail $tmail
- mailer $mailer
- dftsub $dftsub
- admsub $admsub
- page $page
- notify $notify
- dfteditor $dfteditor
- manually B$manually
- mydomain $mydomain
- myname $myname
- myorg $myorg
- uname B$uname
- ghname B$ghname
- v7mail B$v7mail
- newsrc $newsrc
- maxgroups $maxgroups
- buflen $buflen
- lbuflen $lbuflen
- pathlen $pathlen
- datelen $datelen
- namelen $namelen
- fpathlen $fpathlen
- termcap $termcap
- !
- !E!O!F!
- chmod +x lib/setup
-
- echo Part 3 of 7 extracted.
-
-
-